package View;

import java.awt.BorderLayout;

import java.awt.FlowLayout;

import java.awt.GridLayout;
import java.text.DecimalFormat;

import java.util.List;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import Model.IUpdatable;
import Model.MarketPlace.MarketPlaceItem;
import Presenter.MarketPlacePresenter;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class MarketPlaceView extends JPanel implements IUpdatable{
	
	/**
	 * 
	 */
	private final MarketPlacePresenter presenter;

	/**
	 * 
	 */
	private JLabel lblName;

	/**
	 * 
	 */
	private JLabel nameString;

	/**
	 * 
	 */
	private JLabel lblPrice;

	/**
	 * 
	 */
	private JLabel priceString;

	/**
	 * 
	 */
	private JLabel lblQuantity;

	/**
	 * 
	 */
	private JLabel quantityString;

	/**
	 * 
	 */
	private JLabel lblCargo;

	/**
	 * 
	 */
	private JLabel cargoString;

	/**
	 * 
	 */
	private JTextField textField;

	/**
	 * 
	 */
	private JRadioButton rdbtnBuy;

	/**
	 * 
	 */
	private JLabel creditString;

	/**
	 * 
	 */
	private DefaultListModel<MarketPlaceItem> cargoItems;

	/**
	 * 
	 */
	private DefaultListModel<MarketPlaceItem> marketPlaceItems;

	/**
	 * 
	 */
	private JButton confirmButton;

	/**
	 * MarketPlace's View panel
	 */
	private List<MarketPlaceItem> marketItems;
	
	/**
	 * Constrcuts the panel to be added as the MarketPlace GUI
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	
	private void constructView(){
		setLayout(new BorderLayout());
		final JPanel panelA = new JPanel();
		panelA.setLayout(new BorderLayout());
		
		cargoItems = new DefaultListModel<MarketPlaceItem>(); 
		for(MarketPlaceItem item: presenter.getCargoList()){
			cargoItems.addElement(item);
		}
		
		marketPlaceItems = new DefaultListModel<MarketPlaceItem>();
		
		for(MarketPlaceItem item: marketItems){
			marketPlaceItems.addElement(item);
		}
		
	    final JList marketPlaceItemList = new JList(marketPlaceItems);
	    marketPlaceItemList.addListSelectionListener(new ListListener());
	    
	    updateCargo();
	    updateCargoPrices();
	    final JList cargoList = new JList(cargoItems);
	    cargoList.setEnabled(false);
	    cargoList.addListSelectionListener(new ListListener());
	    
	    final JScrollPane left = new JScrollPane(cargoList);
	    final JScrollPane right = new JScrollPane(marketPlaceItemList);
	    
	    final JSplitPane pane = new JSplitPane(
	      JSplitPane.HORIZONTAL_SPLIT, left, right);
	    pane.setDividerLocation(215); 
	   // pane.setPreferredSize(new Dimension(10,10));
	    pane.setOneTouchExpandable(true);
	    panelA.add(pane, BorderLayout.CENTER); 
	    //panel.setPreferredSize(new Dimension(215,215));
	    add(panelA, BorderLayout.CENTER);

	    final JPanel panelB = new JPanel();
	    
	    panelB.setLayout(new GridLayout(0, 2, 20, 0));
		
		final JPanel panel_2 = new JPanel();
		panelB.add(panel_2);
		panel_2.setLayout(new GridLayout(3, 1, 0, 0));
		
		final JPanel panel_5 = new JPanel();
		panel_2.add(panel_5);
		panel_5.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		lblCargo = new JLabel("Ship Cargo:");
		panel_5.add(lblCargo);
		
		cargoString = new JLabel("" + presenter.getCargoNumber());
		panel_5.add(cargoString);
		
		final JPanel panel_6 = new JPanel();
		panel_2.add(panel_6);
		panel_6.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		final JLabel lblCurrentCredit = new JLabel("Current Credit:");
		panel_6.add(lblCurrentCredit);
		
		final DecimalFormat fmt = new DecimalFormat("0.00");
		
		creditString = new JLabel("$" + fmt.format(presenter.getCredits()));
		panel_6.add(creditString);
		
		final JPanel panel_3 = new JPanel();
		panel_2.add(panel_3);
		
		final JButton btnNewButton = new JButton("-");
		btnNewButton.addActionListener(new IncDecButton(marketPlaceItemList, 
		        cargoList, -1));
		panel_3.add(btnNewButton);
		
		textField = new JTextField("1");
		textField.addKeyListener(new TextListener(marketPlaceItemList, cargoList));
		textField.addActionListener(new TextListener(marketPlaceItemList, cargoList));
		panel_3.add(textField);
		textField.setColumns(3);
		
		final JButton btnNewButton_1 = new JButton("+");
		btnNewButton_1.addActionListener(new IncDecButton(marketPlaceItemList, 
		        cargoList, 1));
		panel_3.add(btnNewButton_1);
		
		confirmButton = new JButton("Confirm");
		confirmButton.addActionListener(new ButtonClick(marketPlaceItemList, cargoList));
		panel_3.add(confirmButton);
		
		final ButtonGroup group = new ButtonGroup();
		
		final JPanel panel = new JPanel();
		panelB.add(panel);
		panel.setLayout(new GridLayout(3, 4, 0, 0));
		
		lblName = new JLabel("Name:");
		panel.add(lblName);
		
		nameString = new JLabel("");
		panel.add(nameString);
		
		lblPrice = new JLabel("Price:");
		panel.add(lblPrice);
		
		priceString = new JLabel("");
		panel.add(priceString);
		
		lblQuantity = new JLabel("Quantity");
		panel.add(lblQuantity);
		
		quantityString = new JLabel("");
		panel.add(quantityString);
		
		add(panelB, BorderLayout.SOUTH);
		
		final JPanel panel_1 = new JPanel();
		add(panel_1, BorderLayout.NORTH);
		
		rdbtnBuy = new JRadioButton("Sell");
		rdbtnBuy.addChangeListener(new ButtonListener(marketPlaceItemList, cargoList));
		panel_1.add(rdbtnBuy);
		
		final JRadioButton rdbtnNewRadioButton = new JRadioButton("Buy");
		panel_1.add(rdbtnNewRadioButton);
		rdbtnNewRadioButton.addChangeListener(new ButtonListener(cargoList, 
		        marketPlaceItemList));
		rdbtnBuy.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0) {
				updateStats();
				confirmButton.setEnabled(true);
			}
			
		});
		rdbtnNewRadioButton.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0) {
				updateStats();
				
			}
			
		});
		group.add(rdbtnBuy);
		group.add(rdbtnNewRadioButton);
		rdbtnNewRadioButton.setSelected(true);
	}

	/**
	 * COnstrcutor
	 */
	public MarketPlaceView(){
		presenter = new MarketPlacePresenter();
		marketItems = presenter.getItemList();
		constructView();
	}
	
	/** getter
	 * @return
	 */
	public JLabel getCargoString() {
		return cargoString;
	}

	/**getter
	 * @return
	 */
	public JTextField getTextField() {
		return textField;
	}

	/**getter
	 * @return
	 */
	public JRadioButton getRdbtnBuy() {
		return rdbtnBuy;
	}

	/**
	 * @author Ikenna
	 *
	 */
	private class ListListener implements ListSelectionListener{

		@Override
		public void valueChanged(ListSelectionEvent e) {
			final DecimalFormat fmt = new DecimalFormat("0.00");
			final MarketPlaceItem item = (MarketPlaceItem) ((JList) 
			        e.getSource()).getSelectedValue();
			if(((JList) e.getSource()).getSelectedValue() != null){
				nameString.setText(item.getName());
				priceString.setText("$" + fmt.format(item.getPrice()));
				quantityString.setText("" + item.getQuantity());
				if(!rdbtnBuy.isSelected() && ((JList) e.getSource()).getSelectedValue() != null && !textField.getText().equals("")){
				    try{
				        confirmButton.setEnabled(presenter.canBuy(((MarketPlaceItem) ((JList) e.getSource()).getSelectedValue()), Integer.parseInt(textField.getText())));
				    }catch(NumberFormatException e2){
				        e2.printStackTrace();
				    }
					
				}
				else if(rdbtnBuy.isSelected() && ((JList) e.getSource())
				        .getSelectedValue() != null && !textField.getText().equals("")){
				    try{
				        confirmButton.setEnabled(presenter.canBuy(((MarketPlaceItem) 
				                ((JList) e.getSource()).getSelectedValue()), Integer.parseInt(textField.getText())));
				    }catch(NumberFormatException e3){
				        e3.printStackTrace();
				    }
				}
			}
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
	}
	
	/**
	 * @author Ikenna
	 *
	 */
	public class ButtonListener implements ChangeListener{
		/**
		 * 
		 */
		private final JList other;

		/**
		 * 
		 */
		private final JList current;

		public ButtonListener(JList current, JList other){
			this.current = current;
			this.other = other;
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			if(((JRadioButton) e.getSource()).isSelected()){
				other.setEnabled(true);
				current.setEnabled(false);
				current.clearSelection();
			}
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
	}
	
	/**
	 * @author Ikenna
	 *
	 */
	public class ButtonClick implements ActionListener{
		/**
		 * 
		 */
		private final JList list;

		/**
		 * 
		 */
		private final JList other;
		
		public ButtonClick(JList list, JList other){
			this.list = list;
			this.other = other;
		}
		
		@Override()
		public void actionPerformed(ActionEvent arg0){
			MarketPlaceItem item;
			final DecimalFormat fmt = new DecimalFormat("0.00");
			if((textField.getText() != null && !textField.getText().equals("")) && 
			        (list.getSelectedValue() != null || other.getSelectedValue() != null)){
				if(!rdbtnBuy.isSelected() && list.getSelectedValue() != null){
					item = (MarketPlaceItem) list.getSelectedValue();
					presenter.buy((MarketPlaceItem) list.getSelectedValue(), 
					        Integer.parseInt(textField.getText()));
					updateCargo();
					confirmButton.setEnabled(presenter.canBuy((MarketPlaceItem) list.getSelectedValue(), 
					        Integer.parseInt((textField.getText()))));
				}
				else{
					item = (MarketPlaceItem) other.getSelectedValue();
					if(other.getSelectedValue() != null){	
						presenter.sell(item, marketPlaceItems, 
						        Integer.parseInt(textField.getText()));
						confirmButton.setEnabled(presenter.canSell((MarketPlaceItem) 
						        other.getSelectedValue(), Integer.parseInt((textField.getText()))));
						updateCargo();
						updateStats();
					}
				}
				quantityString.setText("" + item.getQuantity());
				cargoString.setText("" + presenter.getCargoNumber());
				creditString.setText("$" + fmt.format(presenter.getCredits()));	
			}
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
	}
	
	/** ActionListener
	 * @author Ikenna
	 *
	 */
	private class IncDecButton implements ActionListener {
		/**
		 * 
		 */
		private final JList list;

		/**
		 * 
		 */
		private final JList other;

		/**
		 * 
		 */
		private final int num;
		
		public IncDecButton(JList list, JList other, int num){
			this.list = list;
			this.other = other;
			this.num = num;
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if(!textField.getText().equals("")){
				if((Integer.parseInt(textField.getText()) > 0) 
						|| ((Integer.parseInt(textField.getText()) == 0) && num > 0)){
					if(textField.getText().equals("")){
						textField.setText("0");	
					}
					try{
					    textField.setText("" + (Integer.parseInt(textField.getText()) + (num * 1)));
					}catch(NumberFormatException e4){
					    e4.printStackTrace();
					}
				}
				
				if(other.getSelectedValue() != null){
				    try{
				        confirmButton.setEnabled(presenter.canSell((MarketPlaceItem) other.getSelectedValue(), Integer.parseInt(textField.getText())));
				    }catch(NumberFormatException e5){
				        e5.printStackTrace();
				    }
				}
				
				if(list.getSelectedValue() != null){
				    try{
					    confirmButton.setEnabled(presenter.canBuy((MarketPlaceItem) list.getSelectedValue(), Integer.parseInt(textField.getText())));
				    }catch(NumberFormatException e6){
				        e6.printStackTrace();
				    }    
				}
			}
			else {
				if(num > 0){
					textField.setText("1");
				}
			}
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
		
	}
	
	/** ActionListener and KeyListener
	 * @author Ikenna
	 *
	 */
	private class TextListener implements ActionListener, KeyListener {
		/**
		 * 
		 */
		private final JList list;

		/**
		 * 
		 */
		private final JList other;
		
		public TextListener(JList list, JList other){
			this.list = list;
			this.other = other;
		}
		
		@Override
		public void keyPressed(KeyEvent arg0){
			System.out.println("Blank");
		}

		@Override
		public void actionPerformed(ActionEvent e){
		    System.out.println("Blank");
		}

		@Override
		public void keyReleased(KeyEvent arg0) {
			try {
				final int num = Integer.parseInt(textField.getText());
				if(!textField.getText().equals("")){
					if(list.getSelectedValue() != null){
						confirmButton.setEnabled(presenter.canBuy((MarketPlaceItem) 
						        list.getSelectedValue(), num));
					}
					if(other.getSelectedValue() != null){
						confirmButton.setEnabled(presenter.canSell(
						        (MarketPlaceItem) other.getSelectedValue(), num));
					}
				}
			}
			catch(NumberFormatException e){
				textField.setText("");
			}
			
			
		}

		@Override
		public void keyTyped(KeyEvent arg0) {
		    System.out.println("Blank");
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
		
	}

	/* (non-Javadoc)
	 * @see Model.Updatable#update()
	 */
	@Override
	public void update() {
		this.removeAll();
		if(presenter.isPlanetChanged()){
			marketItems = presenter.getItemList();
		}
		
		constructView();
	}
	
	/**
	 * Resets the stats to empty strings
	 */
	private void updateStats(){
		nameString.setText("");
		priceString.setText("");
		quantityString.setText("");
		textField.setText("");
	}
	
	/**
	 * Update the contents in the cargo
	 */
	private void updateCargo(){
		cargoItems.removeAllElements();
		for(MarketPlaceItem item: presenter.getCargoList()){
			if(item.getQuantity() > 0){
				cargoItems.addElement(item);
			}
		}
	}
	
	/**
	 * Updated the prices in the cargo to match the current mareketPlaceItems
	 */
	private void updateCargoPrices(){
		for(MarketPlaceItem item: presenter.getCargoList()){
			for(MarketPlaceItem itemB: marketItems){
				if(item.getName().equals(itemB.getName())){
					item.setPrice(itemB.getPrice());
					break;
				}
			}
		}
	}
	
	@Override
	public String toString(){
		return super.toString();
	}
	
}
